import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;

public class SmartModule2 extends AnAction {



    private Project project;
    //包名
    private String packageName = "";

    private String mClassname;//类开头
    private String mModuleName;//模块名称

private enum CodeType {
    Other, Activity, Fragment, View, Presenter, Service, ServiceImpl, Repository, Api,Layout,Values,
    Manifest,Gradle ,Component,Mode,Bean
}


    @Override
    public void actionPerformed(AnActionEvent e) {

        project = e.getData(PlatformDataKeys.PROJECT);
        init();
        refreshProject(e);


    }


    /**
     * 刷新项目
     *
     * @param e
     */
    private void refreshProject(AnActionEvent e) {
        e.getProject().getBaseDir().refresh(false, true);
    }


    /**
     * 初始化Dialog
     */
    private void init() {
        Kuangkuang myDialog = new Kuangkuang(new Kuangkuang.DialogCallBack() {
            @Override
            public void ok(String moduleName, String className) {
                mModuleName = moduleName;
                mClassname = className;
                packageName = "com." + moduleName.toLowerCase();
                createKtFiles();
                //追加配置到原有的文件中
                //gradle.properties 中配置
                String s  = "\n" +
                        "is"+mModuleName+" =fasle";
                addContent(project.getBasePath()+"/gradle.properties",s);
                //添加setting中配置

                String s1 = ", ':"+mModuleName+"'";
                addContent(project.getBasePath()+"/settings.gradle",s1);
                Messages.showInfoMessage(project, "哈哈,create mvp code success", "title");

            }
        }
        );
        myDialog.setVisible(true);

    }

    private void createKtFiles() {

        createClassFile(CodeType. Other);
        createClassFile( CodeType.Activity);
        createClassFile( CodeType.Fragment);
        createClassFile( CodeType.View);
        createClassFile( CodeType.Presenter);
        createClassFile( CodeType.ServiceImpl);
        createClassFile( CodeType.Service);
        createClassFile( CodeType.Repository);
        createClassFile( CodeType.Api);
        createClassFile( CodeType.Layout );
        createClassFile( CodeType.Values);
        createClassFile( CodeType.Manifest);
        createClassFile( CodeType.Gradle);
        createClassFile( CodeType.Component);
        createClassFile( CodeType.Mode);
        createClassFile( CodeType.Bean);

    }

    /**
     * 获取包名文件路径
     *
     * @return
     */
    private String getAppPath() {

        String appPath = project.getBasePath() + "/" + mModuleName;
        return appPath;
    }

    private void createClassFile( CodeType codeType) {
        String fileName = "";
        String content = "";
        String appPath = getAppPath();
        String packagePath = packageName.replace(".", "/");
        switch (codeType) {

            case Other:
                fileName = "Templateproguard.txt";
                content = ReadTemplateFile(fileName);
                content = dealTemplateContent(content);
                writeToFile(content, appPath  ,  "proguard-rules.pro");

                fileName = "TemplateIml.txt";
                content = ReadTemplateFile(fileName);
                content = dealTemplateContent(content);
                writeToFile(content, appPath  ,  mModuleName+".iml");
                break;
            case Activity:
                fileName = "TemplateActivity.txt";
                content = ReadTemplateFile(fileName);
                content = dealTemplateContent(content);
                writeToFile(content, appPath + "/src/main/java/" + packagePath + "/" + "/ui/activity", mClassname + "Activity.kt");
                break;
            case Fragment:
                fileName = "TemplateFragment.txt";
                content = ReadTemplateFile(fileName);
                content = dealTemplateContent(content);
                writeToFile(content, appPath + "/src/main/java/" + packagePath + "/" + "/ui/fragment", mClassname + "Fragment.kt");
                break;
            case View:
                fileName = "TemplateView.txt";
                content = ReadTemplateFile(fileName);
                content = dealTemplateContent(content);
                writeToFile(content, appPath + "/src/main/java/" + packagePath + "/" + "/presenter/view", mClassname + "View.kt");
                break;
            case Presenter:
                fileName = "TemplatePresenter.txt";
                content = ReadTemplateFile(fileName);
                content = dealTemplateContent(content);
                writeToFile(content, appPath + "/src/main/java/" + packagePath + "/" + "/presenter", mClassname + "Presenter.kt");
                //  writeToFile(content, appPath + mClassname.toLowerCase()+"/presenter", mClassname + "Presenter.kt");
                break;


            case Service:
                fileName = "TemplateService.txt";
                content = ReadTemplateFile(fileName);
                content = dealTemplateContent(content);
                writeToFile(content, appPath + "/src/main/java/" + packagePath + "/" + "/service", mClassname + "Service.kt");
                break;


            case ServiceImpl:
                fileName = "TemplateServiceImpl.txt";
                content = ReadTemplateFile(fileName);
                content = dealTemplateContent(content);
                writeToFile(content, appPath + "/src/main/java/" + packagePath + "/" + "/service/impl", mClassname + "ServiceImpl.kt");
                break;
            case Component:
                fileName = "TemplateComponent.txt";
                content = ReadTemplateFile(fileName);
                content = dealTemplateContent(content);
                writeToFile(content, appPath + "/src/main/java/" + packagePath + "/" + "/injection/component",    mClassname + "Component.kt");
                break;
            case Mode:
                fileName = "TemplateModule.txt";
                content = ReadTemplateFile(fileName);
                content = dealTemplateContent(content);
                writeToFile(content, appPath + "/src/main/java/" + packagePath + "/" + "/injection/module" ,    mClassname + "Module.kt");
                break;

            case Repository:
                fileName = "TemplateRepository.txt";
                content = ReadTemplateFile(fileName);
                content = dealTemplateContent(content);
                writeToFile(content, appPath + "/src/main/java/" + packagePath + "/" + "/data/repository", mClassname + ".kt");
                break;

            case Bean:
                fileName = "TemplateProtocol.txt";
                content = ReadTemplateFile(fileName);
                content = dealTemplateContent(content);
                writeToFile(content, appPath + "/src/main/java/" + packagePath + "/" + "/data/protocol", mClassname + "Repository.kt");
                break;

            case Api:
                fileName = "TemplateApi.txt";
                content = ReadTemplateFile(fileName);
                content = dealTemplateContent(content);
                writeToFile(content, appPath + "/src/main/java/" + packagePath + "/" + "/data/api", mClassname + "Api.kt");
                break;

            case Layout:
                fileName = "TemplateLayout.txt";
                content = ReadTemplateFile(fileName);
                content = dealTemplateContent(content);
                writeToFile(content, appPath + "/src/main/res/layout" ,   "activity_"+mClassname.toLowerCase()+".xml");
                writeToFile(content, appPath + "/src/main/res/layout" ,   "fragment"+mClassname.toLowerCase()+".xml");
                break;
            case Values:
                fileName = "TemplateValues.txt";
                content = ReadTemplateFile(fileName);
                content = dealTemplateContent(content);
                writeToFile(content, appPath + "/src/main/res/values" ,    "strings.xml");
                break;


            case Manifest:
                fileName = "TemplateManifest.txt";
                content = ReadTemplateFile(fileName);
                content = dealTemplateContent(content);
                writeToFile(content, appPath + "/src/main/debug" ,    "AndroidManifest.xml");

                fileName = "TemplateManifest2.txt";
                content = ReadTemplateFile(fileName);
                content = dealTemplateContent(content);
                writeToFile(content, appPath + "/src/main/release" ,    "AndroidManifest.xml");


                break;
            case Gradle:
                fileName = "TemplateGradle.txt";
                content = ReadTemplateFile(fileName);
                content = dealTemplateContent(content);
                writeToFile(content, appPath  ,    "build.gradle");
                break;



        }


    }

    /**
     * 替换模板中字符
     *
     * @param content
     * @return
     */
    private String dealTemplateContent(String content) {

        content = content.replace("$name", mClassname);
        content = content.replace("$modulename", mModuleName);

        content = content.replace("$lll", mClassname.toLowerCase());
        if (content.contains("$packagename")) {
            content = content.replace("$packagename", packageName);
        }
    /*    if (content.contains("$basepackagename")){
            content = content.replace("$basepackagename", packageName + ".base");
        }*/
        content = content.replace("$author", "ywq");
        content = content.replace("$date", getDate());
        return content;
    }

    /**
     * 获取当前时间
     *
     * @return
     */
    public String getDate() {
        Date currentTime = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd");
        String dateString = formatter.format(currentTime);
        return dateString;
    }


    /**
     * 读取模板文件中的字符内容
     *
     * @param fileName 模板文件名
     * @return
     */
    private String ReadTemplateFile(String fileName) {
        InputStream in = null;
        in = this.getClass().getResourceAsStream("/Template/" + fileName);
        String content = "";
        try {
            content = new String(readStream(in));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return content;
    }


    private byte[] readStream(InputStream inputStream) throws IOException {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len = -1;
        try {
            while ((len = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            outputStream.close();
            inputStream.close();
        }

        return outputStream.toByteArray();
    }


    /**
     * 生成
     *
     * @param content   类中的内容
     * @param classPath 类文件路径
     * @param className 类文件名称
     */
    private void writeToFile(String content, String classPath, String className) {
        try {
            File floder = new File(classPath);
            if (!floder.exists()) {
                floder.mkdirs();
            }

            File file = new File(classPath + "/" + className);
            if (!file.exists()) {
                file.createNewFile();
            }

            FileWriter fw = new FileWriter(file.getAbsoluteFile());
            BufferedWriter bw = new BufferedWriter(fw);
            bw.write(content);
            bw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }


    /**
     * 追加原有文件中的内容
     */

    /**
     * 追加文件：使用FileWriter
     *
     * @param fileName
     * @param content
     */
    public static void addContent(String fileName, String content) {
        FileWriter writer = null;
        try {
            // 打开一个写文件器，构造函数中的第二个参数true表示以追加形式写文件
            writer = new FileWriter(fileName, true);
            writer.write(content);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if(writer != null){
                    writer.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }



}
